//
//  Texture.cpp
//  Sinnca Engine v2
//
//  Created by Ryan Oldis on 8/18/11.
//  Copyright 2011 Sinnca Studios. All rights reserved.
//

#include "Texture.h"

#include "computer.h"

texture::texture(std::string n)
{
	glGenTextures(1, &data);
	
	name = n;
}


void texture::load(std::string file)
{
	SDL_Surface *surface;
	
	//printf(file.c_str());
	
	if ( (surface = IMG_Load(file.c_str()) )  )
	{
		// Check that the image's width is a power of 2
		if ( (surface->w & (surface->w - 1)) != 0 )
		{
			printf("warning: image's width is not a power of 2\n");
		}
		
		// Also check if the height is a power of 2
		if ( (surface->h & (surface->h - 1)) != 0 )
		{
			printf("warning: image's height is not a power of 2\n");
		}
		
		// get the number of channels in the SDL surface
		noOfColors = surface->format->BytesPerPixel;
		if (noOfColors == 4)     // contains an alpha channel
		{
			if (surface->format->Rmask == 0x000000ff)
				textureFormat = GL_RGBA;
			else
				textureFormat = GL_BGRA;
		} else if (noOfColors == 3)     // no alpha channel
		{
			if (surface->format->Rmask == 0x000000ff)
				textureFormat = GL_RGB;
			else
				textureFormat = GL_BGR;
		} else {
			printf("warning: the image is not truecolor..  this will probably break\n");
			
		}
		
		
		// Bind the texture object
		glBindTexture( GL_TEXTURE_2D, data );
		
		// Set the texture's stretching properties
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		
		glTexImage2D(GL_TEXTURE_2D, 0, noOfColors, surface->w, surface->h, 0, textureFormat, GL_UNSIGNED_BYTE, surface->pixels);
		
		w = surface->w;
		h = surface->h;
		filename = file;
		
	} else {
		
		printf("Failed to load image\n");
	}
	
	if (surface)
	{
		SDL_FreeSurface(surface);
	}
	
	
}

void texture::bind()
{
	glBindTexture(GL_TEXTURE_2D, data);
}

texture::~texture()
{
	glDeleteTextures(1, &data);
}



// Lua functions

texture* checkTexture(lua_State* L, int ind)
{
	void* ud = dynamic_cast<texture*>((texture*)lua_touserdata(L, ind));
	luaL_argcheck(L, ud != 0, ind, "A 'texture' type is required...");
	
	return *((texture**)ud);
}

static int l_newTexture(lua_State* L)
{
	int n = lua_gettop(L);
	if (n != 1)
	{
		return luaL_error(L, "You need to name this texture...");
	}
	
	texture** tx = (texture**)lua_newuserdata(L, sizeof(texture));
	*tx = new texture(luaL_checkstring(L, 1));
	
	
	lua_getglobal(L, "texture");
	lua_setmetatable(L, -2);
	
	lua_setglobal(L, luaL_checkstring(L, 1));
	
	return 0;
}

static int l_load(lua_State* L)
{
	int n = lua_gettop(L);
	if (n == 2)
	{
		texture* tx = checkTexture(L, 1);
		
		//std::string s = computer->fullPath + luaL_checkstring(L, 2);
		tx->load(computer->fullPath + "/" + luaL_checkstring(L, 2));
	}
	
	return 0;
}


static const luaL_Reg textureFuncs[] = {
	
	{"new", l_newTexture},
	{"loadtex", l_load},
	{NULL, NULL}
	
};

void registerTexture(lua_State* L)
{
	luaL_register(L, "texture", textureFuncs);
	lua_pushvalue(L,-1);
	lua_setfield(L, -2, "__index");
}


